import React from "react";
import ReactDOM from "react-dom/client";

/**
 * state - 状态
 *    简单理解：存放数据的地方，正确的修改这个数据就能引起页面的更新。
 *    注意点：state 只存在于 类组件。函数式组件，没有 state 的玩法。（16.8.0 版本，函数式组件可以通过 hooks 去玩）
 *
 * 1. state 初始化
 *      1. 构造函数中 this.state = { xx: yy, zz: yy }
 *
 *      2. 直接赋值 state 的方式
 *
 * 2. 正确的修改 state
 *      this.state.name = xxx     可以改，但是页面不更新
 *      this.setState({
 *          name: xxx
 *      })
 * 3. setState 可能是异步的
 *      React 为了高效，会将同一时期多次的 setState 合并成一个 setState 来调用
 *          处理方案：
 *              将setState第一个参数改成函数的形式
 *              this.setState((prevState) => {
 *                  return {
 *                      count: prevState.count + 1
 *                  }
 *              })
 *
 *      修改之后，立刻去取值是拿不到最新的值的。
 *          处理方案：
 *              给setState传递第二个参数，是一个回调函数，在这个回调函数中再去获取
 *
 * 4. setState 是合并的操作
 *       （对象合并的操作而不是替换）拿当前传递给 setState 的对象与上次的 state 对象合并之后得到一个全新的 state 对象
 *
 *
 * PS:
 *    组件的 state 数据，或者传递给组件的 props 数据，发生变化的话，就会执行 组件的 render 函数。（生命周期）
 */

class App extends React.Component {
  state = {
    count: 0,
    num: 0,
  };

  handleAdd = () => {
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
    // // 看代码，应该是 5
    // this.setState({ count: this.state.count + 1 });

    this.setState((prevState) => {
      console.log("prevState", prevState);
      return {
        count: prevState.count + 1,
      };
    });
    this.setState((prevState) => {
      console.log("prevState", prevState);
      return {
        count: prevState.count + 1,
      };
    });
    this.setState((prevState) => {
      console.log("prevState", prevState);
      return {
        count: prevState.count + 1,
      };
    });
    this.setState((prevState) => {
      console.log("prevState", prevState);
      return {
        count: prevState.count + 1,
      };
    });
    this.setState((prevState) => {
      console.log("prevState", prevState);
      return {
        count: prevState.count + 1,
      };
    });
  };

  handleAddNum = () => {
    // this.setState({
    //   num: 10,
    // });
    // console.log(this.state.num); // 10，这里猜测是 10 ，但是真实是 0

    this.setState(
      {
        num: 10,
      },
      () => {
        // 这个回调函数，会在 render 之后执行，在这儿还可以拿到真实的DOM对象
        // 跟 vue 中的某个很像 nextTick
        console.log(this.state.num); // 10
        console.log(document.getElementById("p").innerHTML);
      }
    );
  };

  render() {
    console.log("render");
    const { num } = this.state;

    return (
      <div>
        <h1>App</h1>
        <p>count: {this.state.count}</p>
        <p id="p">num: {num}</p>
        <button onClick={this.handleAdd}>点击</button>
        <button onClick={this.handleAddNum}>点击 - num</button>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />);
